﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using ActionSystem.Core;
namespace ActionSystem.Input
{
    /// <summary>
    /// 角色输入模块，每个角色的输入信息在这里保存
    /// </summary>
    public class InputModule : IActionSystemSync
    {
        //输入模块的优先级
        public const int InputPriority = 100;
        private int frameIndex = 0;
        private int depth = 1;
        /// <summary>
        /// 读取按键
        /// </summary>
        private IInputCache reader;
        Dictionary<int, InputBuffer> keys = new Dictionary<int, InputBuffer>();
        public Dictionary<int, InputBuffer> Keys => keys;

        public int Priority => InputPriority;

        public InputModule(IInputCache handler,int depth=10)
        {
            this.reader = handler;
            if(handler==null)
            {
                throw new System.Exception("没有设置InputHandler");
            }
            if (depth < 1)
                depth = 1;
            this.depth = depth;
        }

        public bool AddKey(int key,ButtonType type)
        {
            if(!keys.ContainsKey(key))
            {
                var buffer = InputBuffer.Create();
                buffer.SetDepth(depth);
                buffer.Type = type;
                keys.Add(key, buffer);
                return true;
            }
            return false;
        }
        public void RemoveKey(int key)
        {
            if (keys.ContainsKey(key))
            {
                var buff = keys[key];
                buff.PoolItemDelete();
                keys.Remove(key);                
            }
        }
        /// <summary>
        /// 帧缓冲中按键是否按下
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool IsKeyDown(int key)
        {
            if(keys.ContainsKey(key))
            {
                var buffer = keys[key];
                if(buffer.Type!=ButtonType.Button)
                {
                    return false;
                }
                foreach(var button in buffer.Cache)
                {
                    if(button!=null && button.State== ButtonState.Down && (button.Index==0||button.Index==frameIndex))
                    {
                        button.Index = frameIndex;
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 帧缓冲中按键是否松开
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool IsKeyUp(int key)
        {
            if (keys.ContainsKey(key))
            {
                var buffer = keys[key];
                if (buffer.Type != ButtonType.Button)
                {
                    return false;
                }
                foreach (var button in buffer.Cache)
                {
                    if (button != null && button.State == ButtonState.Up && (button.Index == 0 || button.Index == frameIndex))
                    {
                        button.Index = frameIndex;
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 帧缓冲中摇杆的值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public IEnumerable<Vector2> StickSequence(int key)
        {
            if (keys.ContainsKey(key))
            {
                var buffer = keys[key];
                if (buffer.Type != ButtonType.Stick)
                {
                    yield break;
                }
                foreach (var button in buffer.Cache)
                {
                    yield return button.Stick;
                }
            }
        }
        public Vector2 GetStickThisFrame(int key)
        {
            if (keys.ContainsKey(key))
            {
                var buffer = keys[key];
                if (buffer.Type != ButtonType.Stick)
                {
                    return Vector2.zero ;
                }
                else
                {
                    return buffer.StickValue;
                }
            }
            return Vector2.zero;
        }
        /// <summary>
        /// 是否长按
        /// </summary>
        /// <param name="key"></param>
        /// <param name="frameCount"></param>
        /// <returns></returns>
        public bool IsLongPress(int key,int frameCount)
        {            
            if(frameCount<=0)
            {
                return false;
            }
            int pressindex = 0;
            int index = 0;
            if (keys.ContainsKey(key))
            {
                var buffer = keys[key];
                if (buffer.Type != ButtonType.Button||buffer.IsDown==false)
                {
                    return false;
                }
                foreach (var button in buffer.Cache)
                {
                    if(button!=null)
                    {
                        pressindex = index;
                    }
                    index += 1;
                }
                if(buffer.Cache.Count-pressindex>=frameCount)
                {
                    return true;
                }
            }            
            return false;
        }
        /// <summary>
        /// 双击
        /// </summary>
        /// <param name="key"></param>
        /// <param name="frameCount"></param>
        /// <returns></returns>
        public bool IsDoubleClick(int key,int frameCount)
        {
            int start = 0;
            int end = 0;
            if (keys.ContainsKey(key))
            {
                var buffer = keys[key];
                if (buffer.Type != ButtonType.Button)
                {
                    return false;
                }
                bool findFirst = false;
                InputButton startBtn = null;
                foreach (var button in buffer.Cache)
                {                    

                    if(!findFirst && button !=null&&button.State == ButtonState.Down && button.Index==0||button.Index == frameCount)
                    {
                        findFirst = true;
                        startBtn = button;
                    }
                    if(findFirst && button != null && button.State == ButtonState.Down && button.Index == 0 || button.Index == frameCount)
                    {
                        if(end!=start)
                        {
                            if (end - start <= frameCount)
                            {
                                startBtn.Index = frameIndex;
                                button.Index = frameIndex;
                                return true;
                            }
                            else
                            {
                                start = end;
                                startBtn = button;
                            }
                        }
                        
                    }
                    if (!findFirst)
                        start += 1;
                    end += 1;                                                            
                }
            }
            return false;
        }
        /// <summary>
        /// 当前是否是按下
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool IsPressingThisFrame(int key)
        {
            if (keys.ContainsKey(key))
            {
                var buffer = keys[key];
                if (buffer.Type != ButtonType.Button)
                {
                    return false;
                }
                if(buffer.IsDown)
                {
                    return true;
                }
            }
            return false;
        }
        public void UpdateLogic(float fixedUpdate)
        {
            frameIndex += 1;
            foreach(var key in keys.Keys)
            {
                var buffer = keys[key];
                switch (buffer.Type)
                {
                    case ButtonType.Unkonw:
                        break;
                    case ButtonType.Stick:
                        {
                            buffer.SetStick(reader.Stick(key));
                        }                        
                        break;
                    case ButtonType.Button:
                        {
                            buffer.SetDown(reader.KeyDown(key));                            
                        }
                        break;
                }
            }
            //清除旧的
            foreach(var value in keys.Values)
            {
                value.Clamp();
            }

        }
    }
}

